/*** * type:表单类型 * label:表单名称 * placeholder:默认显示 * isReadOnly:是否只读 * isDisabled:是否禁止 * isRequired:是否必填 * optionList:如果是下拉，复选，单选的数据源 * keyName:有数据源的情况下，绑定的key字段名 * valName:有数据源的情况下，绑定的label字段名 * maxlength:最大输入长度 * colSpan:占位符 * bindFieldName:绑定后段字段名称 * bindFieldVal:双向绑定绑定的具体值 * inputType:input类型 */ // 表单label宽度取表单list的第一个配置项的labelWidth，因为一般都是统一宽度的
<template>
  <section class="form-common">
    <el-form :label-width="filedList[0].labelWidth || '155px'" ref="elform" :model="model" :size="filedList[0].formSize || 'small'" label-position="right">
      <el-row :gutter="20">
        <template v-for="formItem in filedList">
          <template v-if="((formItem.reasonObj && model[formItem.reasonObj.filedName] == formItem.reasonObj.filedVal) || !formItem.reasonObj) && !formItem.isHide">
            <el-col :span="formItem.colSpan || 8" :key="formItem.bindFieldName" :class="{ required: formItem.isRequired }" :style="[{ height: formItem.inputType == 'textarea' ? '' : '50px' }]">
              <el-form-item :label="formItem.label" :prop="formItem.bindFieldName" :rules="[{ required: formItem.isRequired, message: formItem.type == ('select' || 'radio' || 'checkbox' || 'date') ? '请选择' + formItem.label : '请输入' + formItem.label, trigger: ['blur', 'change'] }]">
                <!-- 普通文本 -->
                <template v-if="formItem.type == 'text'">
                  <el-input @input="selectChange(formItem)" :type="formItem.inputType || 'text'" :placeholder="formItem.placeholder || '请输入'" :autosize="{ minRows: 2, maxRows: 10}" :maxlength="formItem.maxlength || 500" :min="formItem.minVal || 0" v-model="model[formItem.bindFieldName]" :readonly="formItem.isReadOnly" :disabled="formItem.isDisabled" @focus="selectChange(formItem)">
                    <template slot="append" v-if="formItem.unit">
                      <span style="color: #333">{{ formItem.unit || '' }}</span>
                    </template>
                    <el-button v-if="formItem.isAppendRightBtn && (!formItem.isAppendRightBtnValue || model[formItem.bindFieldName])" slot="append" :type="formItem.appendRightBtnType || 'primary'" @click="rightBtnFn(formItem.bindFieldName)"> {{ formItem.appendRightBtnTxt }}</el-button>
                  </el-input>
                </template>

                <!-- 下拉 -->
                <template v-if="formItem.type == 'select'">
                  <el-select :remote="formItem.isRemote" :remote-method="res => remoteMethod(res, formItem)" :multiple="formItem.isMultiple" v-model="model[formItem.bindFieldName]" filterable :clearable="formItem.isClearable ? false : true" :disabled="formItem.isDisabled" :placeholder="formItem.placeholder || '请选择'" @change="selectChange(formItem)">
                    <!-- 广告类型合同的选择广告位字段,停车场的选择车位字段，租赁合同的赠送，选择商铺字段选过的就隐藏掉 -->
                    <template v-if="formItem.bindFieldName == 'adKey' || formItem.bindFieldName == 'itemLocation' || formItem.bindFieldName == 'shopCode' || formItem.bindFieldName == 'carParkKey' || formItem.bindFieldName == 'assetKey'">
                      <el-option v-for="(item, index) in formItem.optionList" :key="`${formItem}${index}`" :label="item[formItem.valName]" v-show="item.ifCanChecked" :value="item[formItem.keyName]" />
                    </template>
                    <template v-else>
                      <el-option v-for="(item, index) in formItem.optionList" :key="`${formItem}${index}`" :label="item[formItem.valName]" :value="item[formItem.keyName]" />
                    </template>
                  </el-select>
                </template>

                <!-- 日期选择 -->
                <template v-if="formItem.type == 'date'">
                  <el-date-picker v-model="model[formItem.bindFieldName]" :type="formItem.inputType || 'date'" value-format="timestamp" clearable :disabled="formItem.isDisabled" :placeholder="formItem.placeholder || '请选择'" @change="selectChange(formItem)"></el-date-picker>
                </template>

                <!-- 复选框 -->
                <template v-if="formItem.type == 'checkbox'">
                  <el-checkbox-group @change="selectChange(formItem)" v-model="model[formItem.bindFieldName]" class="self-checkbox-group">
                    <el-checkbox v-for="item in formItem.optionList" :label="item[formItem.keyName]" :key="item[formItem.keyName]" :disabled="formItem.isDisabled">
                      {{ item[formItem.valName] }}
                    </el-checkbox>
                  </el-checkbox-group>
                </template>

                <!-- 单选 -->
                <template v-if="formItem.type == 'radio'">
                  <el-radio-group v-model="model[formItem.bindFieldName]">
                    <el-radio v-for="item in formItem.optionList" @change="radioChange(formItem)" :label="item[formItem.keyName]" :key="item[formItem.keyName]" :disabled="formItem.isDisabled">
                      {{ item[formItem.valName] }}
                    </el-radio>
                  </el-radio-group>
                </template>

                <!-- 按钮 -->
                <template v-if="formItem.type == 'button'">
                  <el-button type="text" @click="typeBtnClick(formItem.bindFieldName)">{{ formItem.buttonTxt }}</el-button>
                </template>
              </el-form-item>
            </el-col>
          </template>
        </template>
      </el-row>
    </el-form>
    <slot name="info"></slot>
  </section>
</template>
<script>
  export default {
    props: {
      //数据源，要显示的表单list
      filedList: {
        type: Array,
        default: () => {
          return [];
        },
      },
      formObj: {
        type: Object,
        default: () => {
          return {};
        },
      },
    },

    watch: {
      filedList: {
        immediate: true,
        deep: true,
        handler(list) {
          let len = Object.keys(this.model);
          //有此判断是因为做下拉框二级联动的时候会改变optionlist，会改变filedList.如果这时用户已经填过表单，调用此方法则会清空，所以在model不是状态则不屌用此方法
          //所以做编辑的时候先调用本组件的clearValidateForm方法
          if (len.length == 0) {
            list.forEach(item => {
              if (item.type == 'checkbox' || (item.type == 'select' && item.isMultiple)) {
                this.$set(this.model, item.bindFieldName, item.bindFieldVal ? item.bindFieldVal : []);
              } else {
                this.$set(this.model, item.bindFieldName, item.bindFieldVal || item.bindFieldVal === 0 || item.bindFieldVal === null ? item.bindFieldVal : '');
              }
            });
          }
        },
      },
      formObj: {
        immediate: true,
        deep: true,
        handler(val) {
          for (let key in val) {
            this.setFiledSource(key, val[key]);
          }
        },
      },
    },

    data() {
      return {
        model: {},
      };
    },

    methods: {
      //校验
      validateForm() {
        let model = false;
        this.$refs.elform.validate(valid => {
          if (valid) {
            model = this.model;
          }
        });
        return model;
      },
      //校验
      returnModel() {
        return this.model;
      },
      //清除校验 初始化model
      clearValidateForm() {
        // this.$refs.elform.resetFields();
        this.initModel();
        this.$nextTick(() => {
          this.clearVerify();
        });
      },
      //input里的按钮点击
      rightBtnFn(filedName) {
        this.$emit('rightBtnFn', {
          filedName: filedName,
          cb: this.setFiledSource,
          model: this.model,
        });
      },
      //给某字段赋值
      setFiledSource(filedName, filedVal) {
        this.$set(this.model, filedName, filedVal);
      },
      //单选事件
      radioChange(formItem) {
        this.$emit('radioChange', {
          filedName: formItem.bindFieldName,
          filedVal: this.model[formItem.bindFieldName],
          cb: this.setFiledSource,
          model: this.model,
        });
        this.Change(formItem);
      },
      //下拉框事件
      selectChange(formItem) {
        this.$emit('selectChange', {
          formItem: formItem,
          filedName: formItem.bindFieldName,
          influenceFiledName: formItem.influenceFiledName,
          filedVal: this.model[formItem.bindFieldName],
          cb: this.setFiledSource,
          cbList: this.setFiledoptionList, // 赋值下拉框的optionList
          model: this.model,
          setValidateFn: this.setValidateFn,
          setDisadledFn: this.setDisadledFn,
        });

        if (formItem.displayKey && formItem.optionList && formItem.optionList.length) {
          for (let i = 0; i < formItem.optionList.length; i++) {
            if (formItem.optionList[i][formItem.keyName] == this.model[formItem.bindFieldName]) {
              this.$set(this.model, formItem.displayKey, formItem.optionList[i][formItem.valName]);
              break;
            }
          }
        }
      },
      remoteMethod(res, formItem) {
        console.log(res, formItem);
        this.$emit('remoteMethod', {
          remoteVal: res,
          formItem: formItem,
          cb: this.setFiledSource,
          cbList: this.setFiledoptionList, // 赋值下拉框的optionList
          model: this.model,
        });
      },
      Change(formItem) {
        this.$set(this.formObj, formItem.bindFieldName, this.model[formItem.bindFieldName]);
        this.$emit('Change', formItem);
      },
      //设置一些字段的必填与否 filedList:需要控制哪些字段 Ex:["filed1,filed2"]  isRequired:是否加校验 Ex:true false
      setValidateFn(filedList, isRequired) {
        this.filedList.forEach(item => {
          if (filedList.indexOf(item.bindFieldName) > -1) {
            item.isRequired = isRequired;
          }
        });
      },
      setDisadledFn(filedList, isDisabled){
        this.filedList.forEach(item => {
          if (filedList.indexOf(item.bindFieldName) > -1) {
            item.isDisabled = isDisabled;
          }
        });
      },
      // 赋值下拉框的optionList
      setFiledoptionList(filedName, optionList) {
        this.filedList.forEach(item => {
          if (item.bindFieldName == filedName) {
            item.optionList = optionList;
          }
        });
      },

      //按钮类型点击
      typeBtnClick(filedName) {
        this.$emit('typeBtnClick', {
          filedName: filedName,
          cb: this.setFiledSource,
          model: this.model,
        });
      },
      //清空校验
      clearVerify() {
        this.$refs.elform.clearValidate();
      },
      //初始化model
      initModel() {
        this.model = {};
      },
    },
  };
</script>
<style lang="scss">
  .required {
    & > .el-form-item {
      & > .el-form-item__label:before {
        content: '*';
        color: #f56c6c;
        margin-right: 4px;
      }
    }
  }
  .self-checkbox-group {
    line-height: 27px;
  }
  .el-radio {
    span {
      font-size: 16px;
    }
    .el-radio__inner {
      width: 15px;
      height: 15px;
    }
  }
  .form-common {
    .el-input-group__append,
    .el-input-group__prepend {
      // padding: 0 10px;
    }
  }
</style>
